这是一份专为**初中级开发者**编写的《典狱长网关（DYZ Gateway）插件对接白皮书》。

为了让您能够轻松上手，本文档聚焦于**“您的插件如何与网关通信”**这一核心环节。并附带了大量针对新手的避坑指南。

---

# 🔰 典狱长网关 (DYZ Gateway) 插件开发白皮书

## 💡 1. 架构速览：我们要开发什么？

在典狱长系统中，网关（Gateway）是一个独立的 Python Web 程序，它像一个“交警中枢”。我们需要开发两个组件与它配合：

1. **服务端插件 (Server Plugin)**：运行在游戏服务器上。负责告诉网关“我开服了”，并听从网关的指挥（比如踢人）。
2. **客户端插件 (Client Plugin)**：运行在玩家电脑上。负责收集玩家的进程、异常行为，并加密打包汇报给网关。

---

## 🛠️ 2. 服务端插件开发指南 (Game Server ⇌ Gateway)

**新手认知**：服务端插件与网关的通信是**双向**的。不仅您要发数据给网关，网关也会发指令给您。因此，您的插件必须在游戏服务器本地**开启一个简易的 HTTP 服务**。

### 第一步：向网关“报到”（主动注册）

当您的游戏服务端启动时，需要第一时间给网关发一个 HTTP POST 请求，告诉网关您的存在。

* **请求地址**: `POST http://<网关IP>:<网关端口>/api/register_server`
* **请求头 (Headers)**: `Content-Type: application/json`
* **发送的数据 (Body)**:
```json
{
  "name": "一区：雷霆万钧", 
  "ip": "192.168.1.100",  
  "port": 8080            
}

```


> **🛑 新手避坑指南**：
> * `ip` 和 `port` **绝对不能乱填**！这代表着您的插件在本地开启的 HTTP 监听地址。网关稍后会通过 `http://192.168.1.100:8080` 来联系您。
> * 如果网关使用的是“单服版”授权，这里的 `ip` 必须和网关在同一台物理机或同一个局域网内，否则会被网关拒绝（返回 403 错误）。
> 
> 



### 第二步：开启监听，等待网关指令 (重点)

您需要在插件中使用您熟悉的语言（如 C++、Delphi、C#）启动一个 HTTP 服务，监听您刚刚注册的端口（比如 8080），并实现以下几个 API 路由。

网关会以 `POST` 或 `GET` 的方式访问您的这些路由，**您的插件收到请求后，去调用游戏引擎的底层功能，然后返回一段 JSON 告诉网关结果即可**。

| 路由路径 | 请求方法 | 网关发给您的参数 (JSON) | 您的插件需要做的事 | 您的插件应该返回 (JSON) |
| --- | --- | --- | --- | --- |
| `/api/status` | `GET` | 无 | 啥也不用做，证明您还活着 | 任意 HTTP 200 状态码即可 |
| `/api/getplayerlist` | `GET` | 无 | 读取游戏引擎，获取当前所有在线玩家名字 | `{"players": [{"name": "张三"}, {"name": "李四"}]}` |
| `/api/kickplayer` | `POST` | `{"characterName": "张三"}` | 调用游戏引擎的踢人功能，把张三踢下线 | `{"success": true}` |
| `/api/sendmsg` | `POST` | `{"name": "张三", "msg": "警告"}` | 调用游戏引擎给张三发一段文字警告 | `{"success": true}` |
| `/api/set_sell_player` | `POST` | `{"enabled": true}` | 修改游戏内的拦截摆摊/交易开关 | `{"success": true}` |

---

## 💻 3. 客户端插件开发指南 (Player Client ➔ Gateway)

**新手认知**：客户端插件（反作弊模块）通常是用 C++ 或 Rust 编写的 DLL。它不需要开启服务端，只需要**单向**给网关“打小报告”即可。为了防止外挂作者抓包，报告内容必须**加密**。

### 第一步：理解加密流程

网关采用的是 `AES-128-CTR` 对称加密算法。

* **密钥 (AES KEY)**: (严格 16 字节)
* **偏移量 (AES IV)**: (严格 16 字节)
* **RC4 密钥**: (咨询典狱长)
* **加密步骤 (必背公式)**：
`原始 JSON 字符串` ➔ `AES 加密` ➔ `二进制数据` ➔ `Base64 编码` ➔ `最终生成的乱码字符串`。

### 第二步：组装上报的数据包

您需要将组装好的 JSON，按照上述步骤加密后，发送给网关：

* **请求地址**: `POST http://<网关IP>:<网关端口>/api/submit_message`
* **请求头**: `Content-Type: application/json`
* **外层外壳**:
```json
{
  "message": "这里填入您加密并Base64后的那串长长的乱码"
}

```



### 第三步：明文数据长什么样？(加密前的 JSON)

这是整个系统最核心的数据结构，请严格按照格式生成字符串：

```json
{
  "server_id": "192.168.1.100:8080", 
  "role": "游戏角色名",
  "game_name": "一区雷霆",
  "msg_type": "PROCESS_FULL",
  "data": "[{\"pid\": 1234, \"name\": \"cheat.exe\", \"exe_path\": \"C:\\\\cheat.exe\", \"crc32\": \"FFFF\"}]"
}

```

> **🛑 新手避坑指南**：
> 1. **`server_id` 极其重要**：它必须是 `游戏服务器IP:游戏服务器端口`。网关就是靠这个字段，把玩家的数据和具体的游戏服匹配起来的！如果这里填错，数据会被网关直接抛弃。
> 2. **`data` 字段的值，通常是一个字符串**，而不是一个 JSON 对象。如果里面包含数组或对象，请将其序列化（转义）为字符串。
> 
> 

### 常用消息类型 (`msg_type`) 一览

| `msg_type` | 含义 | `data` 字段应该填什么？ |
| --- | --- | --- |
| `PROCESS_FULL` | 全量进程上报 | 包含所有进程信息的 JSON 数组字符串 |
| `SPEED_CHECK` | 移动加速检测 | 毫秒数值（字符串格式，如 `"11500"`） |
| `ENV_CHECK` | 虚拟机/环境检测 | 特定格式字符串，如 `"vm:1|reason:检测到VMware"` |
| `SCREENSHOT_DATA` | 上报玩家屏幕截图 | 图片文件二进制流，直接转为 **Base64** 的字符串。不要加 `data:image/png;base64,` 前缀！ |

---

## 🎓 4. 给新人的 4 条黄金建议 (Best Practices)

1. **先用工具测试，再写代码**
* 不要一上来就用 C++ 写网络请求和加密！先打开 `Postman` 或者写一段简单的 `Python` 脚本（可参考网关源码目录下的 `test_client.py`），尝试手动组装一段数据发送给网关，看看网关后台能不能收到。跑通了逻辑，再动手写 C++/Rust。


2. **警惕“阻塞”游戏主线程**
* 在写服务端插件时，无论您是发注册请求，还是响应网关的 HTTP 请求，**请务必使用异步操作或新开线程**！千万不要在游戏引擎的主循环（Main Loop）里做 HTTP 等待，否则一旦网络卡顿，整个游戏服务器都会被卡死。


3. **客户端上报要有“节制” (限流)**
* 客户端不要死循环式地疯狂上报进程（比如 1 毫秒发一次）。合理的做法是：玩家刚上线时发送一次全量进程 (`PROCESS_FULL`)，之后每隔几秒扫描一次，**仅当发现新进程时**才上报 (`PROCESS_DIFF`)。这能极大减轻网关的并发压力。


4. **日志，日志，还是日志！**
* 在插件开发初期，请把所有发出的 JSON 明文、接收到的 HTTP 状态码打印到本地 log 文件中。99% 的对接失败（比如 AES 补码错误、JSON 漏了双引号、IP 填错）都可以通过看日志一眼排查出来。